﻿/*
* This software is the confidential and proprietary
* information of NetBay
* Such confidential information should not be disclosed
* NetBay copyright(c) 2010
*/
#region Using
using System;
using System.Collections.Generic;
using NetBay.Core.BusinessEntities.Workflow;
using Rio.Flow.Business.Repository.Translator;
using Rio.Flow.DataAccess;
using System.Data;
using System.Linq;

#endregion

namespace Rio.Flow.Business.Repository
{
    /// <summary>
    /// Message repository
    /// </summary>
    public class WorkflowDefinitionRepository 
    {
        /// <summary>
        /// Returns all workflow definitions
        /// </summary>
        /// <returns></returns>
        public static List<WorkflowDefinition> GetWorkflowDefinitions()
        {
            var definitions = new List<WorkflowDefinition>();
            definitions = WorkflowDefinitionTranslator.TranslateWorkflowDefinitions(DA_WorkflowDefinition.GetWorkflowDefinitions());

            // add actions & conditions
            foreach (var def in definitions)
            {
                def.Actions = GetDefinitionActions(def.Identifier);
                def.Conditions = GetDefinitionConditions(def.Identifier);

                if (def.ReceiversType == ReceiverType.Auto)
                    def.ReceiverGroupId = GetReceiversGroupId(def.Identifier);

            }

            return definitions;
        }

        /// <summary>
        /// Returns a definition by this id
        /// </summary>
        /// <returns></returns>
        public static WorkflowDefinition GetWorkflowDefinitionById(long wkfDefId)
        {
            var def = new WorkflowDefinition();
            def = WorkflowDefinitionTranslator.TranslateWorkflowDefinition(DA_WorkflowDefinition.GetWorkflowDefinitionById(wkfDefId));

            // add actions & conditions
            def.Actions = GetDefinitionActions(def.Identifier);
            def.Conditions = GetDefinitionConditions(def.Identifier);
            if (def.ReceiversType == ReceiverType.Auto)
                def.ReceiverGroupId = GetReceiversGroupId(def.Identifier);

            return def;
        }

        /// <summary>
        /// Returns a definition by this name
        /// </summary>
        /// <returns></returns>
        public static WorkflowDefinition GetWorkflowDefinitionByName(string wkfDefName)
        {
            var def = new WorkflowDefinition();
            def = WorkflowDefinitionTranslator.TranslateWorkflowDefinition(DA_WorkflowDefinition.GetWorkflowDefinitionByName(wkfDefName));

            // add actions & conditions
            def.Actions = GetDefinitionActions(def.Identifier);
            def.Conditions = GetDefinitionConditions(def.Identifier);
            if (def.ReceiversType == ReceiverType.Auto)
                def.ReceiverGroupId = GetReceiversGroupId(def.Identifier);

            return def;
        }

        /// <summary>
        /// Returns a list of defintions for a foldertype
        /// </summary>
        /// <returns></returns>
        public static List<WorkflowDefinition> GetWorkflowDefinitionsByFolderTypeId(long folderTypeId)
        {
            var definitions = WorkflowDefinitionTranslator.TranslateWorkflowDefinitions(DA_WorkflowDefinition.GetWorkflowDefinitionsByFolderTypeId(folderTypeId));

            // add actions & conditions
            foreach (var def in definitions)
            {
                def.Actions = GetDefinitionActions(def.Identifier);
                def.Conditions = GetDefinitionConditions(def.Identifier);
                if (def.ReceiversType == ReceiverType.Auto)
                    def.ReceiverGroupId = GetReceiversGroupId(def.Identifier);
            }

            return definitions;
        }

        /// <summary>
        /// Gets the workflow definition childs.
        /// </summary>
        /// <param name="wkfDefId">The WKF def id.</param>
        /// <returns></returns>
        public static List<WorkflowDefinition> GetWorkflowDefinitionChilds(long wkfDefId)
        {
            var definitions = new List<WorkflowDefinition>();
            definitions = WorkflowDefinitionTranslator.TranslateWorkflowDefinitions(DA_WorkflowDefinition.GetWorkflowDefinitionChildById(wkfDefId));

            // add actions & conditions
            foreach (var def in definitions)
            {
                def.Actions = GetDefinitionActions(def.Identifier);
                def.Conditions = GetDefinitionConditions(def.Identifier);

                if (def.ReceiversType == ReceiverType.Auto)
                    def.ReceiverGroupId = GetReceiversGroupId(def.Identifier);
            }

            return definitions;
        }

        /// <summary>
        /// Returns all actions for a definition
        /// </summary>
        /// <returns></returns>
        public static List<WorkflowAction> GetDefinitionActions(long wkfDefId)
        {
            return WorkflowDefinitionTranslator.TranslateActionsOrConditions(DA_WorkflowDefinition.GetActions(wkfDefId));
        }

        /// <summary>
        /// Returns all conditions for a definition
        /// </summary>
        /// <returns></returns>
        public static List<WorkflowCondition> GetDefinitionConditions(long wkfDefId)
        {
            return WorkflowDefinitionTranslator.TranslateConditions(DA_WorkflowDefinition.GetConditions(wkfDefId));
        }

        /// <summary>
        /// Add a definition With groups identifiers as receivers.
        /// </summary>
        /// <param name="definition">The definition</param>
        /// <param name="actions">List of availables actions for the definition</param>
        /// <param name="conditions">List of availables conditions for the definition</param>
        /// <param name="receiverIndexId">Index INdentifier</param>
        /// <returns></returns>
        public static bool AddWorkflowDefinition(WorkflowDefinition definition, Dictionary<long, bool> actions, List<long> conditions, long receiverIndexId, bool keepChilds = true)
        {
            definition.ReceiversType = ReceiverType.Index;
            return DA_WorkflowDefinition.AddWorkflowDefinition(definition, actions, conditions, receiverIndexId, keepChilds);
        }

        /// <summary>
        /// Add a definition With index identifier as receivers.
        /// </summary>
        /// <param name="definition">The definition</param>
        /// <param name="actions">List of availables actions for the definition</param>
        /// <param name="conditions">List of availables conditions for the definition</param>
        /// <param name="receiversGroupIds">List of group identifier</param>
        /// <returns></returns>
        public static bool AddWorkflowDefinition(WorkflowDefinition definition, Dictionary<long, bool> actions, List<long> conditions, List<long> receiversGroupIds, bool keepChilds = true)
        {
            definition.ReceiversType = ReceiverType.Auto;
            return DA_WorkflowDefinition.AddWorkflowDefinition(definition, actions, conditions, receiversGroupIds, keepChilds);
        }

        /// <summary>
        /// Add an action or a condition to the definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <param name="wkfActCondId">Workflow action identifier</param>
        /// <returns></returns>
        public static bool AddActionOrConditionToDefinition(long wkfDefId, long wkfActCondId, bool isTrigger)
        {
            return DA_WorkflowDefinition.AddActionOrConditionToDefinition(wkfDefId, wkfActCondId, isTrigger);
        }

        /// <summary>
        /// Add an action to the definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <param name="wkfAction">Workflow action type</param>
        /// <returns></returns>
        public static bool AddActionToDefinition(long wkfDefId, long wkfAction, bool isTrigger)
        {
            return DA_WorkflowDefinition.AddActionOrConditionToDefinition(wkfDefId, Convert.ToInt32(wkfAction), isTrigger);
        }

        /// <summary>
        /// Add a condition to the definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <param name="wkfAction">Workflow condition type</param>
        /// <returns></returns>
        public static bool AddConditionToDefinition(long wkfDefId, long wkfCondition)
        {
            return DA_WorkflowDefinition.AddActionOrConditionToDefinition(wkfDefId, Convert.ToInt32(wkfCondition));
        }

        /// <summary>
        /// Delete a definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <returns></returns>
        public static bool DeleteDefinition(long wkfDefId)
        {
            return DA_WorkflowDefinition.DeleteDefinition(wkfDefId);
        }

        /// <summary>
        /// Deactivate a definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <returns></returns>
        public static bool DeactivateDefinition(long wkfDefId, DateTime DeactivationDate)
        {
            return DA_WorkflowDefinition.DeactivateDefinition(wkfDefId, DeactivationDate);
        }

        /// <summary>
        /// Gets the receivers id.
        /// </summary>
        /// <param name="wkfDefId">The WKF def id.</param>
        /// <returns></returns>
        public static List<long> GetReceiversGroupId(long wkfDefId)
        {
            List<long> result = new List<long>();
            IDataReader l_oIDataReader = DA_WorkflowDefinition.GetReceiversGroupId(wkfDefId);
            using (l_oIDataReader)
            {
                // Read all rows
                while (l_oIDataReader.Read())
                {
                    result.Add(Convert.ToInt64(l_oIDataReader["rg_id"]));
                }
            }
            return result;
        }

        /// <summary>
        /// Get all definitions to start by foldertype and condition.
        /// </summary>
        /// <param name="folderTypeId">Foldertype identifier</param>
        /// <param name="startCondition">Starting condition</param>
        /// <returns></returns>
        public static List<WorkflowDefinition> GetDefinitionsToStart(long folderTypeId, long startCondition)
        {
            List<WorkflowDefinition> result = new List<WorkflowDefinition>();
            var definitions = GetWorkflowDefinitionsByFolderTypeId(folderTypeId).Where(p => p.ParentId == null); 
            foreach (var item in definitions)
            {
                foreach (var condition in item.Conditions)
                {
                    if (condition.ActionOrConditionId == startCondition && item.ParentId == null)
                    {
                        result.Add(item);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// Gets the definitions child to start.
        /// </summary>
        /// <param name="wkfDefId">The WKF def id.</param>
        /// <param name="startCondition">The start condition.</param>
        /// <returns></returns>
        public static List<WorkflowDefinition> GetDefinitionsChildToStart(long wkfDefId, long startCondition)
        {
            List<WorkflowDefinition> result = new List<WorkflowDefinition>();
            var definitions = GetWorkflowDefinitionChilds(wkfDefId); 
            foreach (var item in definitions)
            {
                foreach (var condition in item.Conditions)
                {
                    if (condition.ActionOrConditionId == startCondition)
                    {
                        result.Add(item);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// Determines whether [has definitions to start] for [the specified folder type id].
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="startCondition">The start condition.</param>
        /// <returns></returns>
        public static bool HasDefinitionsToStart(long folderTypeId, long startCondition)
        {
            bool result = false;
            var definitions = GetWorkflowDefinitionsByFolderTypeId(folderTypeId);
            foreach (var item in definitions)
            {
                foreach (var condition in item.Conditions)
                {
                    if (condition.ActionOrConditionId == startCondition && item.ParentId == null)
                    {
                        result = true;
                        break;
                    }
                }
            }
            return result;
        }
    }
}